package com.qny.ai.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qny.ai.common.ErrorCode;
import com.qny.ai.dto.chat.CreateConversationRequest;
import com.qny.ai.dto.chat.SendMessageRequest;
import com.qny.ai.dto.conversation.ConversationWithRoleDTO;
import com.qny.ai.entity.AppRole;
import com.qny.ai.entity.Conversation;
import com.qny.ai.entity.Message;
import com.qny.ai.exception.BusinessException;
import com.qny.ai.mapper.AppRoleMapper;
import com.qny.ai.mapper.ConversationMapper;
import com.qny.ai.mapper.MessageMapper;
import com.qny.ai.service.ConversationService;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.MessageType;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
public class ConversationServiceImpl implements ConversationService {

    private final ConversationMapper conversationMapper;
    private final MessageMapper messageMapper;
    private final ChatClient chatClient;
    private final AppRoleMapper appRoleMapper;

    @Override
    public Long createConversation(CreateConversationRequest request) {
        Conversation c = Conversation.builder()
                .userId(request.getUserId())
                .roleId(request.getRoleId())
                .startTime(LocalDateTime.now())
                .isActive(1)
                .lastLanguage(StringUtils.hasText(request.getLanguage()) ? request.getLanguage() : "zh")
                .build();
        int inserted = conversationMapper.insert(c);
        if (inserted != 1) {
            throw new BusinessException(ErrorCode.SERVER_ERROR.getCode(), "创建会话失败");
        }
        
        // 发送开场白
        try {
            AppRole role = appRoleMapper.selectById(request.getRoleId());
            if (role != null && role.getOpeningLine() != null && !role.getOpeningLine().trim().isEmpty()) {
                String openingLine = role.getOpeningLine();
                
                // 替换模板变量
                openingLine = openingLine.replace("{role_name}", role.getName());
                openingLine = openingLine.replace("{personality}", role.getPersonality() != null ? role.getPersonality() : "");
                openingLine = openingLine.replace("{background}", role.getBackground() != null ? role.getBackground() : "");
                
                // 保存开场白到数据库
                Message openingMsg = Message.builder()
                        .conversationId(c.getId())
                        .content(openingLine)
                        .originalContent(null)
                        .language(c.getLastLanguage())
                        .isUserMessage(0)
                        .emotion("friendly")
                        .timestamp(LocalDateTime.now())
                        .build();
                messageMapper.insert(openingMsg);
                
                System.out.println("[CONVERSATION] 开场白已发送: " + openingLine);
            }
        } catch (Exception e) {
            System.err.println("[CONVERSATION] 发送开场白失败: " + e.getMessage());
        }
        
        return c.getId();
    }

    @Override
    public boolean endConversation(Long conversationId) {
        Conversation c = conversationMapper.selectById(conversationId);
        if (c == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND);
        }
        if (c.getIsActive() != null && c.getIsActive() == 0) {
            return true;
        }
        c.setIsActive(0);
        c.setEndTime(LocalDateTime.now());
        return conversationMapper.updateById(c) == 1;
    }

    @Override
    public Long sendUserMessage(SendMessageRequest request) {
        Conversation c = conversationMapper.selectById(request.getConversationId());
        if (c == null || c.getIsActive() == null || c.getIsActive() == 0) {
            throw new BusinessException(ErrorCode.CONFLICT.getCode(), "会话不存在或已结束");
        }
        Message m = Message.builder()
                .conversationId(request.getConversationId())
                .content(request.getContent())
                .originalContent(null)
                .language(StringUtils.hasText(request.getLanguage()) ? request.getLanguage() : c.getLastLanguage())
                .isUserMessage(1)
                .emotion(null)
                .timestamp(LocalDateTime.now())
                .build();
        int inserted = messageMapper.insert(m);
        if (inserted != 1) {
            throw new BusinessException(ErrorCode.SERVER_ERROR.getCode(), "发送消息失败");
        }
        // 更新会话最近语言
        c.setLastLanguage(m.getLanguage());
        conversationMapper.updateById(c);

        // 构建系统 persona 与历史上下文（取最近 10 条）
        AppRole role = appRoleMapper.selectById(c.getRoleId());
        String persona = buildPersona(role);
        List<com.fasterxml.jackson.databind.JsonNode> ignored = null; // 占位避免导入冲突

        List<org.springframework.ai.chat.messages.Message> chatHistory = new ArrayList<>();
        if (StringUtils.hasText(persona)) {
            chatHistory.add(new SystemMessage(persona));
        }
        List<Message> history = messageMapper.selectList(new LambdaQueryWrapper<Message>()
                .eq(Message::getConversationId, c.getId())
                .orderByAsc(Message::getTimestamp)
                .last("limit 10"));
        for (Message h : history) {
            if (h.getIsUserMessage() != null && h.getIsUserMessage() == 1) {
                chatHistory.add(new UserMessage(h.getContent()));
            } else {
                chatHistory.add(new AssistantMessage(h.getContent()));
            }
        }

        String botReply;
        try {
            botReply = chatClient.prompt()
                    .messages(chatHistory)
                    .call()
                    .content();
            
            // 如果回复为空或太短，使用默认回复
            if (botReply == null || botReply.trim().length() < 2) {
                botReply = "抱歉，我现在有点忙，请稍后再试。";
            }
        } catch (Exception e) {
            System.err.println("[AI] DashScope调用失败: " + e.getMessage());
            // 根据异常类型提供不同的回复
            if (e.getMessage() != null && e.getMessage().contains("timeout")) {
                botReply = "抱歉，网络有点慢，请稍后再试。";
            } else if (e.getMessage() != null && e.getMessage().contains("401")) {
                botReply = "AI服务暂时不可用，请稍后再试。";
            } else {
                botReply = "抱歉，我现在有点忙，请稍后再试。";
            }
        }

        Message bot = Message.builder()
                .conversationId(request.getConversationId())
                .content(botReply)
                .originalContent(null)
                .language(c.getLastLanguage())
                .isUserMessage(0)
                .emotion("neutral")
                .timestamp(LocalDateTime.now())
                .build();
        messageMapper.insert(bot);
        return m.getId();
    }

    private String buildPersona(AppRole role) {
        if (role == null) return "";
        StringBuilder sb = new StringBuilder();
        if (StringUtils.hasText(role.getName())) {
            sb.append("你正在扮演角色：").append(role.getName()).append("。\n");
        }
        if (StringUtils.hasText(role.getBackground())) {
            sb.append("背景：").append(role.getBackground()).append("\n");
        }
        if (StringUtils.hasText(role.getPersonality())) {
            sb.append("性格：").append(role.getPersonality()).append("\n");
        }
        if (StringUtils.hasText(role.getLanguageStyle())) {
            sb.append("语言风格：").append(role.getLanguageStyle()).append("\n");
        }
        if (StringUtils.hasText(role.getPromptTemplate())) {
            sb.append("提示：").append(role.getPromptTemplate()).append("\n");
        }
        sb.append("请以该角色的语气与用户对话，保持人设一致，回答简洁有温度。");
        return sb.toString();
    }

    @Override
    public Page<Message> listMessages(Long conversationId, int pageNo, int pageSize) {
        Conversation c = conversationMapper.selectById(conversationId);
        if (c == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND);
        }
        Page<Message> page = new Page<>(pageNo, pageSize);
        return messageMapper.selectPage(page, new LambdaQueryWrapper<Message>()
                .eq(Message::getConversationId, conversationId)
                .orderByAsc(Message::getTimestamp));
    }

    @Override
    public Conversation getById(Long id) {
        return conversationMapper.selectById(id);
    }

    @Override
    public Page<Conversation> listConversations(Long userId, Long roleId, Integer active, int pageNo, int pageSize) {
        Page<Conversation> page = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<Conversation> qw = new LambdaQueryWrapper<>();
        if (userId != null) {
            qw.eq(Conversation::getUserId, userId);
        }
        if (roleId != null) {
            qw.eq(Conversation::getRoleId, roleId);
        }
        if (active != null) {
            qw.eq(Conversation::getIsActive, active);
        }
        qw.orderByDesc(Conversation::getStartTime);
        return conversationMapper.selectPage(page, qw);
    }

    @Override
    public Page<ConversationWithRoleDTO> listConversationsWithRole(Long userId, Long roleId, Integer active, int pageNo, int pageSize) {
        Page<Conversation> page = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<Conversation> qw = new LambdaQueryWrapper<>();
        if (userId != null) {
            qw.eq(Conversation::getUserId, userId);
        }
        if (roleId != null) {
            qw.eq(Conversation::getRoleId, roleId);
        }
        if (active != null) {
            qw.eq(Conversation::getIsActive, active);
        }
        qw.orderByDesc(Conversation::getStartTime);
        
        Page<Conversation> conversations = conversationMapper.selectPage(page, qw);
        
        // 转换为带角色信息的DTO
        Page<ConversationWithRoleDTO> result = new Page<>(pageNo, pageSize);
        result.setTotal(conversations.getTotal());
        result.setPages(conversations.getPages());
        result.setCurrent(conversations.getCurrent());
        result.setSize(conversations.getSize());
        
        List<ConversationWithRoleDTO> dtoList = new ArrayList<>();
        for (Conversation conv : conversations.getRecords()) {
            AppRole role = appRoleMapper.selectById(conv.getRoleId());
            ConversationWithRoleDTO dto = ConversationWithRoleDTO.builder()
                    .id(conv.getId())
                    .userId(conv.getUserId())
                    .roleId(conv.getRoleId())
                    .roleName(role != null ? role.getName() : "未知角色")
                    .roleAvatarUrl(role != null ? role.getAvatarUrl() : null)
                    .roleDescription(role != null ? role.getDescription() : null)
                    .conversationTitle(conv.getTitle() != null ? conv.getTitle() : (role != null ? role.getName() + "的对话" : "未知对话"))
                    .startTime(conv.getStartTime())
                    .endTime(conv.getEndTime())
                    .isActive(conv.getIsActive())
                    .lastLanguage(conv.getLastLanguage())
                    .build();
            dtoList.add(dto);
        }
        result.setRecords(dtoList);
        
        return result;
    }

    @Override
    public boolean deleteConversation(Long conversationId, Long userId) {
        // 验证会话是否存在且属于当前用户
        Conversation conversation = conversationMapper.selectById(conversationId);
        if (conversation == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND.getCode(), "会话不存在");
        }
        
        if (!conversation.getUserId().equals(userId)) {
            throw new BusinessException(ErrorCode.FORBIDDEN.getCode(), "无权限删除此会话");
        }
        
        // 删除会话相关的所有消息
        messageMapper.delete(new LambdaQueryWrapper<Message>()
                .eq(Message::getConversationId, conversationId));
        
        // 删除会话
        int deleted = conversationMapper.deleteById(conversationId);
        return deleted == 1;
    }
}


